<?php

declare(strict_types=1);

namespace App\Lib;

use Firebase\JWT\JWT;

class JwtToken
{
    public static $data = [];   //返回結果
    public static $exp = 28800;  //token的过期时间
    public static $overtime = 25920000;  //刷新token的过期时间

    /**
     * @param array $info
     * @param string $flag  前台后台区分  1后台  2前台
     * @param string $key jwt的签发密钥，验证token的时候需要用到
     * @return array
     * @Description
     * @example
     * @author wuxian
     * @since 2020-04-17
     */
    public static function authorizations(array $info, $key, string $flag = '1') : array
    {
        $access_token = self::createJwt($info, $key, self::$exp, $flag);
        $refresh_token = self::createJwt($info, $key, self::$overtime, $flag);
        return ['token' => $access_token, 'refresh_token'=>$refresh_token];
    }

    // 生成token
    public static function createJwt(array $info, $key, int $exp = 0, string $flag = '1'): string
    {
        $nbf = time();
        empty($exp) ? $exp = self::$exp : '';
        $expire = $nbf + $exp;
        $token = [
            "iss" => $flag,  //签发者 可以为空
            "aud" => "", //面象的用户，可以为空
            "iat" => $nbf, //签发时间
            "nbf" => $nbf, //在什么时候jwt开始生效  （这里表示生成10秒后才生效）
            "exp" => $expire, //token 过期时间
            "uid" => $info['id'], //记录的userid的信息
            'account' => $info['account'], // 用户账号
            'name' => $info['name'],
            'company_id' => $info['company_id'],
        ];
        return JWT::encode($token, $key);
    }

    public static function checkToken(array $header, $key) : array
    {
        if (!isset($header[0])) {
            self::$data = ['errCode' => 4001,'msg' => '沒有Token值'];
            return self::$data;
        }
        $checkJwtToken = static::verifyJwt($header[0], $key);
        self::$data = $checkJwtToken;
        return $checkJwtToken;
    }

    //校验jwt权限API
    protected static function verifyJwt(string $jwt, $key): array
    {
        // 处理jwt的值 Bearer
        $jwt_list = explode(" ", $jwt);
        if ($jwt_list[0] != 'Bearer') {
            return ['errCode' => 4006, 'msg' => 'Token格式不对'];
        }
        $jwt = $jwt_list[1];

        try {
            $jwtAuth = json_encode(JWT::decode($jwt, $key, array('HS256')));
            $authInfo = json_decode($jwtAuth, true);

            return ['errCode' => 0, 'data' => $authInfo];
        } catch (\Firebase\JWT\SignatureInvalidException $e) {
            return [
                'errCode' => 4002,
                'msg' => 'Token无效'
            ];
        } catch (\Firebase\JWT\ExpiredException $e) {
            return [
                'errCode' => 4003,
                'msg' => 'Token过期'
            ];
        } catch (Exception $e) {
            return [
                'errCode' => 4004,
                'msg' => $e->getMessage()
            ];
        }
    }

    /**
     * 刷新重新生成并返回token
     * @return array
     */
    public static function refreshToken(string $refresh_token, $key, array $change_info=[]) : array
    {
        try {
            // 处理jwt的值 Bearer
            $jwt_list = explode(" ", $refresh_token);
            if ($jwt_list[0] != 'Bearer') {
                return ['errCode' => 4006, 'msg' => 'Token格式不对'];
            }
            $refresh_token = $jwt_list[1];

            $jwtAuth = json_encode(JWT::decode($refresh_token, $key, array('HS256')));
            $authInfo = json_decode($jwtAuth, true);
            $info = [
                'id' => $change_info['id'] ?? $authInfo['uid'],
                'account' => $change_info['account'] ?? $authInfo['account'],
                'name' =>$change_info['name'] ?? $authInfo['account'],
                'company_id' => $change_info['company_id'] ?? $authInfo['company_id']
            ];
            return ['errCode' => 0, 'data' => self::createJwt($info, $key, self::$exp, $authInfo['iss']), 'msg' => ''];
        } catch (\Firebase\JWT\SignatureInvalidException $e) {
            return [
                'errCode' => 4002,
                'msg' => 'Token无效'
            ];
        } catch (\Firebase\JWT\ExpiredException $e) {
            return [
                'errCode' => 4002,
                'msg' => '刷新Token过期,请重新登录'
            ];
        } catch (Exception $e) {
            return [
                'errCode' => 4004,
                'msg' => $e->getMessage()
            ];
        }
    }
}
